package tk.hoopy.zedtown.levels;

import tk.hoopy.zedtown.assets.AssetManager;
import tk.hoopy.zedtown.assets.Tile;

public class Generator {
	
	private Tile grass,smallBuilding1,smallBuilding2,smallBuilding3,verticalStreet,horizontalStreet,street;
	private Tile longBuilding, tallBuilding, superLongBuilding, superTallBuilding, giantBuilding;
	
	public Generator() {
		grass = AssetManager.GetTileFromName("Grass");
		smallBuilding1 = AssetManager.GetTileFromName("Building_Small_1");
		smallBuilding2 = AssetManager.GetTileFromName("Building_Small_2");
		smallBuilding3 = AssetManager.GetTileFromName("Building_Small_3");
		longBuilding = AssetManager.GetTileFromName("Building_Long");
		tallBuilding = AssetManager.GetTileFromName("Building_Tall");
		superLongBuilding = AssetManager.GetTileFromName("Building_Superlong");
		superTallBuilding = AssetManager.GetTileFromName("Building_Supertall");
		giantBuilding = AssetManager.GetTileFromName("Building_Giant");
		verticalStreet = AssetManager.GetTileFromName("Street_Vertical");
		horizontalStreet = AssetManager.GetTileFromName("Street_Horizontal");
		street = AssetManager.GetTileFromName("Street");
	}
	
	public Chunk[][] GenerateLevel(int size, float difficulty) {
		
		Chunk[][] chunkTable = new Chunk[size][size];
		
		for(int i=0;i<size;i++) {
			for(int z=0;z<size;z++) {
				Chunk newChunk = GenerateChunk(i,z);
				chunkTable[i][z] = newChunk;
			}
		}
		
		return chunkTable;
	}
	
	public Chunk GenerateChunk(int x, int y) {
		int posX = x*3, posY = y*3;
		Chunk newChunk = new Chunk();
		newChunk.SetPosition(posX,posY);
		
		double conditionOne = Math.random();
		boolean hasHorizontal = false,hasVertical = false;
		Tile[][] tileList = {	{grass,grass,verticalStreet},
							{grass,grass,verticalStreet},
							{horizontalStreet,horizontalStreet,street}	};
		
		for(int i=0;i<3;i++)
			for(int z=0;z<3;z++)
				tileList[i][z] = PickSmallBuilding();
		
		if(conditionOne >= 0.3 && conditionOne <= 0.7) {
			hasHorizontal = true;
			hasVertical = true;
		} else if(conditionOne < 0.3 && conditionOne > 0.025) {
			hasHorizontal = true;
		} else if(conditionOne > 0.7 && conditionOne < 0.975) {
			hasVertical = true;
		}
		
		if(!hasVertical && !hasHorizontal && Math.random() < 0.1) {		//Giant Building
			for(int i=0;i<3;i++)
				for(int z=0;z<3;z++)
					tileList[i][z] = AssetManager.NULL_TILE;
			tileList[0][0] = giantBuilding;
		} else if(!hasHorizontal && Math.random() < 0.15) {				//Supertall Building
			if(Math.random() > 0.5) {
				tileList[0][0] = superTallBuilding;
				tileList[1][0] = AssetManager.NULL_TILE;
				tileList[2][0] = AssetManager.NULL_TILE;
				Tile[] tempTileList = GenerateMediumBuilding(false);
				tileList[0][1] = tempTileList[0];
				tileList[1][1] = tempTileList[1];
				tileList[2][1] = tempTileList[2];
				tempTileList = GenerateMediumBuilding(false);
				tileList[0][2] = tempTileList[0];
				tileList[1][2] = tempTileList[1];
				tileList[2][2] = tempTileList[2];
			} else {
				tileList[0][1] = superTallBuilding;
				tileList[1][1] = AssetManager.NULL_TILE;
				tileList[2][1] = AssetManager.NULL_TILE;
				Tile[] tempTileList = GenerateMediumBuilding(false);
				tileList[0][0] = tempTileList[0];
				tileList[1][0] = tempTileList[1];
				tileList[2][0] = tempTileList[2];
				tempTileList = GenerateMediumBuilding(false);
				tileList[0][2] = tempTileList[0];
				tileList[1][2] = tempTileList[1];
				tileList[2][2] = tempTileList[2];
			}
		} else if(!hasVertical && Math.random() < 0.15) {				//Superwide Building
			if(Math.random() > 0.5) {
				tileList[0][0] = superLongBuilding;
				tileList[0][1] = AssetManager.NULL_TILE;
				tileList[0][2] = AssetManager.NULL_TILE;
				tileList[1] = GenerateMediumBuilding(true);
				tileList[2] = GenerateMediumBuilding(true);
			} else {
				tileList[1][0] = superLongBuilding;
				tileList[1][1] = AssetManager.NULL_TILE;
				tileList[1][2] = AssetManager.NULL_TILE;
				tileList[0] = GenerateMediumBuilding(true);
				tileList[2] = GenerateMediumBuilding(true);
			}
		
		} else {
			if(hasHorizontal && hasVertical) {
				int first = -1;
				double conditionTwo = Math.random();
				double conditionThree = Math.random();
				if(conditionTwo < 0.2) {
					first = 0;
					tileList[0][0] = PickMediumBuilding(true);
					tileList[0][1] = AssetManager.NULL_TILE;
				} else if(conditionTwo < 0.4) {
					first = 1;
					tileList[1][0] = PickMediumBuilding(true);
					tileList[1][1] = AssetManager.NULL_TILE;
				}
				if(first == -1) {
					if(conditionThree < 0.2) {
						tileList[0][0] = PickMediumBuilding(false);
						tileList[1][0] = AssetManager.NULL_TILE;
					} else if(conditionThree < 0.4) {
						tileList[0][1] = PickMediumBuilding(false);
						tileList[1][1] = AssetManager.NULL_TILE;
					}
				}
			} else if(hasHorizontal) {
				
			}else if(hasVertical) {
			
			} else {
				
			}
		}
		
		if(hasHorizontal) {
			tileList[2][0] = horizontalStreet;
			tileList[2][1] = horizontalStreet;
			tileList[2][2] = street;
		}
		
		if(hasVertical) {
			tileList[0][2] = verticalStreet;
			tileList[1][2] = verticalStreet;
			tileList[2][2] = street;
		}
		
		for(int i=0;i<3;i++)
			for(int z=0;z<3;z++)
				newChunk.AddTile(tileList[z][i],i,z);
		
		return newChunk;
	}
	
	private Tile PickSmallBuilding() {
		double conditionOne = Math.random();
		if(conditionOne > 0.7)
			return smallBuilding1;
		else if(conditionOne > 0.4)
			return smallBuilding2;
		else if(conditionOne > 0.1)
			return smallBuilding3;
		else
			return grass;
	}
	
	private Tile[] GenerateMediumBuilding(boolean isHorizontal) {
		Tile[] newTiles = new Tile[3];
		if(Math.random() < 0.2) {
			if(Math.random() < 0.5) {
				newTiles[0] = PickMediumBuilding(isHorizontal);
				newTiles[1] = AssetManager.NULL_TILE;
				newTiles[2] = PickSmallBuilding();
			} else {
				newTiles[0] = PickSmallBuilding();
				newTiles[1] = PickMediumBuilding(isHorizontal);
				newTiles[2] = AssetManager.NULL_TILE;
			}
		} else {
			newTiles[0] = PickSmallBuilding();
			newTiles[1] = PickSmallBuilding();
			newTiles[2] = PickSmallBuilding();
		}
		return newTiles;
	}
	
	private Tile PickMediumBuilding(boolean isHorizontal) {
		if(isHorizontal)
			return longBuilding;
		else
			return tallBuilding;
		
	}
	
	
}
